package com.example.asapp.aspect;

import com.example.asapp.annotation.HasRole;
import com.example.asapp.base.BaseService;
import com.example.asapp.exception.AuthUnexpectException;
import com.example.asapp.user.detail.Detail;
import com.example.asapp.user.detail.DetailDao;
import com.example.asapp.user.detail.DetailService;
import com.example.asapp.user.role.Role;
import com.example.asapp.util.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/*
    @auth fbz
    @date 2021/5/26/10:35
*/

@Component
@Aspect
@Slf4j
public class HasRoleAspect {

    @Autowired
    HttpServletRequest request;

    @Pointcut("@annotation(com.example.asapp.annotation.HasRole)")
    void pointcut() {

    }

    @Autowired
    BaseService baseService;

    @Before("pointcut() && @annotation(hasRole)")
    public void advice(JoinPoint joinPoint, HasRole hasRole) throws AuthUnexpectException {
        log.info("{} need role :{}",joinPoint.getSignature().getName(), hasRole.value());
        if(!baseService.getLogin()){
            throw new AuthUnexpectException();
        }
        String token=request.getHeader("token");
        String id=request.getHeader("id");
        log.info("token is {}",token);



        log.info("login user id is:{}",id);
        Detail detail=detailDao.findById(id).get();
        for (Role role : detail.getRoleList()) {
            log.info("has role {}",role.getValue());
        }
        String[] rolesNeed=hasRole.value();
        boolean authResult=true;
        for (String roleNeed:rolesNeed){
            authResult=authResult && arrHasStr(detail.getRoleList(),roleNeed);
        }
        if (authResult){
            log.info("user({}) has the auth:{}",id,hasRole.value());
        }else {
            throw new AuthUnexpectException();
        }

    }

    private boolean arrHasStr(List<Role> roleList, String roleNeed) {
        List<Role> roleRes=roleList.stream()
                .filter(e-> e.getValue().equals(roleNeed)).collect(Collectors.toList());
        return !roleRes.isEmpty();
    }


    @Autowired
    DetailDao detailDao;

    @Autowired
    RedisService redisService;

}
